import sys
from common import *
from main import GRA_RESULT_PATH, _get_output_name, FILE_NAME, OUT_PUT_GRA


class AnalyseOutput():
    def __init__(self, Token):
        if not Token:
            print("\033[31m请正确输入Token，检查Token是否为空\033[0m")
            return
        # 检查输入的Token是否为空

        self.ReduceWithOutput(Token)

    def Get_Dealing_Type(self, Str_In, Type_In):
        if Type_In == 'KW' or Type_In == 'OP' or Type_In == 'SE':  # 如果是这几种情况，则将输入的字符作为待处理的类型
            Res_Type = Str_In

        else:  # 以类型作为待处理目标
            Res_Type = Type_In
            if Type_In == 'STR':
                Res_Type = 'STRING'

        return Res_Type

    def ReduceWithOutput(self, Token_in):
        GRA_RESULT_PATH = _get_output_name(FILE_NAME, OUT_PUT_GRA)
        resultFile = open(GRA_RESULT_PATH, 'w', encoding='utf-8')

        RowNumber = 1

        Token_in.append(['#', '#'])
        stack = ['#', Start_flag]
        # 初始化参数，包括加入结束符号，开始符号

        for i, [Token_str, Token_type] in enumerate(Token_in):

            DealingType = self.Get_Dealing_Type(Token_str, Token_type)

            Cur_State = ''  # 用于标记当前的状态
            while Cur_State != 'move':

                stack_top = stack.pop()

                if stack_top == DealingType:
                    if stack_top == DealingType == '#':  # 对应三种可能情况之一
                        print(f'{RowNumber}\t/\t{stack_top}\taccept')
                        resultFile.write(f'{RowNumber}\t/\t{stack_top}\taccept\n')
                        break
                    Cur_State = 'move'
                    OutPut_tmp = DealingType
                    if DealingType == 'ORDERBY':
                        OutPut_tmp = 'ORDER BY'
                    if DealingType == 'GROUPBY':
                        OutPut_tmp = 'GROUP BY'

                    print(f'{RowNumber}\t/\t{stack_top}#{OutPut_tmp}\t{Cur_State}')
                    resultFile.write(f'{RowNumber}\t/\t{stack_top}#{OutPut_tmp}\t{Cur_State}\n')
                    RowNumber += 1

                else:
                    Cur_State = 'reduction'

                    try:
                        tmp = M[(stack_top, DealingType)]
                        rule_num = tmp[2]
                        OutPut_tmp = DealingType
                        if DealingType == 'ORDERBY':
                            OutPut_tmp = 'ORDER BY'
                        if DealingType == 'GROUPBY':
                            OutPut_tmp = 'GROUP BY'

                    except:  # 出错
                        resultFile.write(f'ERROR:不匹配，栈顶:{stack_top}   终结符:{DealingType}\n')
                        print(f'ERROR:不匹配，栈顶:{stack_top}   终结符:{DealingType}')
                        print(f'栈:{stack}')
                        sys.exit()

                    if tmp[1] == '$':  # 如果是空，对应情况2
                        if OutPut_tmp == '#':
                            OutPut_tmp = ' '
                        print(f'{RowNumber}\t{rule_num}\t{stack_top}#{OutPut_tmp}\treduction')
                        resultFile.write(f'{RowNumber}\t{rule_num}\t{stack_top}#{OutPut_tmp}\treduction\n')
                        RowNumber += 1
                    else:
                        right_str_list = tmp[1].split(' ')  # 对应三种可能动作之三
                        for Each_Element in reversed(right_str_list):  # 反序
                            stack.append(Each_Element)  # 入栈

                        print(f'{RowNumber}\t{rule_num}\t{stack_top}#{OutPut_tmp}\t{Cur_State}')
                        resultFile.write(f'{RowNumber}\t{rule_num}\t{stack_top}#{OutPut_tmp}\t{Cur_State}\n')
                        RowNumber += 1
        pass
